package com.rockcent.wechat.helper;

import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.mall.lib.domain.MallWechatConfig;
import com.rockcent.mall.lib.domain.MessageAutoreply;
import com.rockcent.mall.lib.domain.MessageReplyRule;
import com.rockcent.mall.lib.domain.MessageReplyRuleContent;
import com.rockcent.mall.lib.domain.enumclass.WechatMessageCode;
import com.rockcent.mall.lib.domain.enumclass.WechatMessageType;
import com.rockcent.mall.lib.dto.MallWechatMenuListDTO;
import com.rockcent.mall.lib.repository.WechatConfigRepository;
import com.rockcent.service.MallWechatMessageConfigService;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by HK on 16/10/12.
 */
@Component
public class WechatHelper {

    private static final Logger log = LoggerFactory.getLogger(WechatHelper.class);

    public static final String sEncodingAESKey = "WtXLiyk28BaGC1ChARcpkgp0FIhqxFTCjNYLm86ucFL"; // 不需要修改
    public static final String sToken = "GWH2015GO"; // 不需要修改
    /**
     * 对接微信公众号 service
     *
     * @return
     */
    @Autowired
    private HashMap<String, WxMpService> wxMpServiceMap;
    /**
     * 对接微信小程序 service
     *
     * @return
     */
    @Autowired
    private HashMap<String, WxMpService> wxAppServiceMap;

    @Autowired
    private WechatConfigRepository wechatConfigRepository;
    @Autowired
    private MallWechatMessageConfigService mallWechatMessageConfigService;

    private WxMpService setWxMpServiceMap (String domain){
        MallWechatConfig config = wechatConfigRepository.queryWechatConfigByDomain(domain);
        log.info("======================>wechat config : {}", config);
        if (config != null) {
            log.info("======================>domian : {} ,wxMpService is not exist,auto create", domain);
            String appId = config.getAppid();
            String appSecret = config.getAppSecret();
            String partnerId = config.getMchid();
            String partnerKey = config.getConfigKey();

            WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
            wxMpInMemoryConfigStorage.setAppId(appId); // 设置微信公众号的appid
            wxMpInMemoryConfigStorage.setSecret(appSecret); // 设置微信公众号的app corpSecret
            wxMpInMemoryConfigStorage.setToken(sToken); // 设置微信公众号的token
            wxMpInMemoryConfigStorage.setAesKey(sEncodingAESKey); // 设置微信公众号的EncodingAESKey

            // 微信支付商户号
            wxMpInMemoryConfigStorage.setPartnerId(partnerId);
            wxMpInMemoryConfigStorage.setPartnerKey(partnerKey);

            WxMpService wxMpService = new WxMpServiceImpl();
            wxMpService.setWxMpConfigStorage(wxMpInMemoryConfigStorage);

            wxMpServiceMap.put(domain, wxMpService);
            return wxMpService;
        }
        return null;
    }

    private WxMpService setWxAppServiceMap (String domain){
        MallWechatConfig config = wechatConfigRepository.queryWechatConfigByDomain(domain);
        log.info("======================>config : {}", config);
        if (config != null) {
            log.info("======================>domian : {} ,wxMpService is not exist,auto create", domain);
            String appId = config.getAppid();
            String appSecret = config.getAppSecret();
            String partnerId = config.getMchid();
            String partnerKey = config.getConfigKey();

            WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
            wxMpInMemoryConfigStorage.setAppId(appId); // 设置微信公众号的appid
            wxMpInMemoryConfigStorage.setSecret(appSecret); // 设置微信公众号的app corpSecret
            wxMpInMemoryConfigStorage.setToken(sToken); // 设置微信公众号的token
            wxMpInMemoryConfigStorage.setAesKey(sEncodingAESKey); // 设置微信公众号的EncodingAESKey

            // 微信支付商户号
            wxMpInMemoryConfigStorage.setPartnerId(partnerId);
            wxMpInMemoryConfigStorage.setPartnerKey(partnerKey);

            WxMpService wxMpService = new WxMpServiceImpl();
            wxMpService.setWxMpConfigStorage(wxMpInMemoryConfigStorage);

            wxAppServiceMap.put(domain, wxMpService);
            return wxMpService;
        }
        return null;
    }


    public WxMpService getWxMpService(String domain) {

        WxMpService wxMpService = wxMpServiceMap.get(domain);
        if (wxMpService == null) {
            wxMpService = this.setWxMpServiceMap(domain);
        } else {
            WxMpConfigStorage storage = wxMpService.getWxMpConfigStorage();
            if (null != storage) {
                //判断AccessToken是否过期
                if (storage.isAccessTokenExpired()) {
                    wxMpService = this.setWxMpServiceMap(domain);
                }
                String appId0 = storage.getAppId();
                String appSecret0 = storage.getSecret();
                String partnerId0 = storage.getPartnerId();
                String partnerKey0 = storage.getPartnerKey();
                String token0 = storage.getToken();
                String aesKey0 = storage.getAesKey();
                log.info("======================>appId0：" + appId0);
                log.info("======================>appSecret0：" + appSecret0);
                log.info("======================>partnerId0：" + partnerId0);
                log.info("======================>partnerKey0：" + partnerKey0);
                log.info("======================>token0：" + token0);
                log.info("======================>aesKey0：" + aesKey0);

            }

        }


        return wxMpService;
    }

    public WxMpService getWxAppService(String domain) {

        WxMpService wxMpService = wxAppServiceMap.get(domain);
        if (wxMpService == null) {
            wxMpService = this.setWxAppServiceMap(domain);
        } else {
            WxMpConfigStorage storage = wxMpService.getWxMpConfigStorage();
            if (null != storage) {
                //判断AccessToken是否过期
                if (storage.isAccessTokenExpired()) {
                    wxMpService = this.setWxAppServiceMap(domain);
                }
                String appId0 = storage.getAppId();
                String appSecret0 = storage.getSecret();
                String partnerId0 = storage.getPartnerId();
                String partnerKey0 = storage.getPartnerKey();
                String token0 = storage.getToken();
                String aesKey0 = storage.getAesKey();
                log.info("======================>wxapp appId0：" + appId0);
                log.info("======================>wxapp appSecret0：" + appSecret0);
                log.info("======================>wxapp partnerId0：" + partnerId0);
                log.info("======================>wxapp partnerKey0：" + partnerKey0);
                log.info("======================>wxapp token0：" + token0);
                log.info("======================>wxapp aesKey0：" + aesKey0);

            }

        }


        return wxMpService;
    }

    /**
     * 转换微信的树形菜单
     *
     * @param wxMenu
     * @param menuListDTO
     */
    public WxMenu convertWechatMenu(WxMenu wxMenu, List<MallWechatMenuListDTO> menuListDTO) {
        if (menuListDTO == null || menuListDTO.size() == 0) {
            return null;
        }


        List<WxMenuButton> buttons = new ArrayList<>();
        for (MallWechatMenuListDTO dto : menuListDTO) {
            WxMenuButton button = setMenuButton(dto);
            buttons.add(button);
            if (dto.getChildren() != null && dto.getChildren().size() > 0) {
                List<WxMenuButton> subButtons = new ArrayList<>();
                for (MallWechatMenuListDTO subDTO : dto.getChildren()) {
                    WxMenuButton suButton = setMenuButton(subDTO);
                    subButtons.add(suButton);
                    if (subDTO.getChildren() != null && subDTO.getChildren().size() > 0) {
                        List<WxMenuButton> subButtons2 = new ArrayList<>();
                        for (MallWechatMenuListDTO subDTO2 : subDTO.getChildren()) {
                            WxMenuButton suButton2 = setMenuButton(subDTO2);
                            subButtons2.add(suButton2);
                        }
                        suButton.setSubButtons(subButtons2);
                    }
                }
                button.setSubButtons(subButtons);
            }
        }
        wxMenu.setButtons(buttons);
        return wxMenu;
    }

    /**
     * 转换微信菜单
     *
     * @param subDTO
     * @return
     */
    private WxMenuButton setMenuButton(MallWechatMenuListDTO subDTO) {
        WxMenuButton suButton = new WxMenuButton();
        if (subDTO != null) {
            suButton.setName(subDTO.getName());
            suButton.setType(subDTO.getMenuType());
            suButton.setUrl(subDTO.getPageUrl());
            suButton.setMediaId(subDTO.getMediaId());
        }
        return suButton;
    }

    /**
     * 关注回复消息
     * @param toUser
     * @param fromUser
     * @param mallId
     * @return
     */
    public String subscribeAndReplyMsg(String code, String toUser, String fromUser, Long mallId) {
        String result = null;
        log.info("subscribeAndReplyMsg code:{},toUser:{},fromUser:{},mallId:{}",code,toUser,fromUser,mallId);
        MessageAutoreply messageAutoreply = mallWechatMessageConfigService.findByCodeAndMallId(code,mallId);
        log.info("subscribeAndReplyMsg messageAutoreply:{}",messageAutoreply);
        if(messageAutoreply!=null) {
            if(messageAutoreply.getType().equals(WechatMessageType.TEXT)) {
                result = textMsg(toUser,fromUser,messageAutoreply.getContent());
            } else if(messageAutoreply.getType().equals(WechatMessageType.IMAGE)) {
                result = imageMsg(toUser,fromUser,messageAutoreply.getMediaId());
            } else if(messageAutoreply.getType().equals(WechatMessageType.VOICE)) {
                result = voiceMsg(toUser,fromUser,messageAutoreply.getMediaId());
            } else if(messageAutoreply.getType().equals(WechatMessageType.VIDEO)) {
                result = videoMsg(toUser,fromUser,messageAutoreply.getMediaId(),messageAutoreply.getMediaTitle(),messageAutoreply.getMediaDesc());
            }
        }
        return result;
    }

    /**
     * 关键字回复消息
     * @param toUser
     * @param fromUser
     * @param mallId
     * @param content
     * @return
     */
    public List<String> keywordReplyMsg(String toUser, String fromUser, Long mallId, String content) {
        List<String> msgs = null;
        log.info("keywordReplyMsg toUser:{},fromUser:{},mallId:{},content:{}",toUser,fromUser,mallId,content);
        if(mallId==null || StringUtils.isEmpty(content)) {
            return msgs;
        }
        List<MessageReplyRule> rules = mallWechatMessageConfigService.findRulesByKeywordAndMallId(content,mallId);
        if(rules!=null && rules.size()>0) {
            msgs = new ArrayList<>();
            for(MessageReplyRule rule:rules) {
                if(rule.getAllReply() == Whether.NO) {
                    MessageReplyRuleContent ruleContent = mallWechatMessageConfigService.findRuleContentByRuleId(rule.getId());
                    String result = replyRuleContentMsg(ruleContent,toUser,fromUser);
                    if(StringUtils.isNotEmpty(result)) {
                        msgs.add(result);
                    }
                } else if(rule.getAllReply() == Whether.YES) {
                    List<MessageReplyRuleContent> contents = mallWechatMessageConfigService.findRuleContentsByRuleId(rule.getId());
                    if(contents!=null) {
                        int size = contents.size();
                        if(size==1) {
                            MessageReplyRuleContent messageReplyRuleContent = contents.get(0);
                            String result = replyRuleContentMsg(messageReplyRuleContent, toUser, fromUser);
                            if (StringUtils.isNotEmpty(result)) {
                                msgs.add(result);
                            }
                        } else if(size>1) {
                            for (MessageReplyRuleContent messageReplyRuleContent : contents) {
                                String result = replyRuleContentKefuMsg(messageReplyRuleContent, toUser, fromUser);
                                if (StringUtils.isNotEmpty(result)) {
                                    msgs.add(result);
                                }
                            }
                        }
                    }
                }
                break;
            }
        }
        return msgs;
    }

    /**
     * 组装各类型消息
     * @param ruleContent
     * @param toUser
     * @param fromUser
     * @return
     */
    private String replyRuleContentKefuMsg(MessageReplyRuleContent ruleContent,String toUser, String fromUser) {
        String result = null;
        WechatMessageType type = ruleContent.getType();
        if(type.equals(WechatMessageType.TEXT)) {
            result = setTextWxMpKefuMessage(fromUser,ruleContent.getContent()).toJson();
        } else if(type.equals(WechatMessageType.IMAGE)) {
            result = setImageWxMpKefuMessage(fromUser,ruleContent.getMediaId()).toJson();
        } else if(type.equals(WechatMessageType.VOICE)) {
            result = setVoiceWxMpKefuMessage(fromUser,ruleContent.getMediaId()).toJson();
        } else if(type.equals(WechatMessageType.VIDEO)) {
            result = setVideoWxMpKefuMessage(fromUser,ruleContent.getMediaId(),ruleContent.getMediaTitle(),ruleContent.getMediaDesc()).toJson();
        } else if(type.equals(WechatMessageType.NEWS)) {
            result = setNewsWxMpKefuMessage(fromUser,ruleContent.getMediaId()).toJson();
        }
        return result;
    }

    /**
     * 发送文本消息
     * @param fromUser
     * @param content
     * @return
     */
    private WxMpKefuMessage setTextWxMpKefuMessage(String fromUser, String content) {
        return setWxMpKefuMessage(WxConsts.CUSTOM_MSG_TEXT,fromUser,null,null,null,content);
    }

    /**
     * 发送图片消息
     * @param fromUser
     * @param mediaId
     * @return
     */
    private WxMpKefuMessage setImageWxMpKefuMessage(String fromUser,String mediaId) {
        return setWxMpKefuMessage(WxConsts.CUSTOM_MSG_IMAGE,fromUser,mediaId,null,null,null);
    }

    /**
     * 发送语音消息
     * @param fromUser
     * @param mediaId
     * @return
     */
    private WxMpKefuMessage setVoiceWxMpKefuMessage(String fromUser,String mediaId) {
        return setWxMpKefuMessage(WxConsts.CUSTOM_MSG_VOICE,fromUser,mediaId,null,null,null);
    }

    /**
     * 发送视频消息
     * @param fromUser
     * @param mediaId
     * @return
     */
    private WxMpKefuMessage setVideoWxMpKefuMessage(String fromUser,String mediaId,String title,String description) {
        return setWxMpKefuMessage(WxConsts.CUSTOM_MSG_VIDEO,fromUser,mediaId,title,description,null);
    }

    /**
     * 发送图文消息
     * @param fromUser
     * @param mediaId
     * @return
     */
    private WxMpKefuMessage setNewsWxMpKefuMessage(String fromUser,String mediaId) {
        return setWxMpKefuMessage(WxConsts.CUSTOM_MSG_MPNEWS,fromUser,mediaId,null,null,null);
    }

    /**
     * 组装各类客服消息
     * @return
     */
    private WxMpKefuMessage setWxMpKefuMessage(String type,String fromUser,String mediaId,String title,String description,String content) {
        WxMpKefuMessage wxMpKefuMessage = new WxMpKefuMessage();
        wxMpKefuMessage.setToUser(fromUser);
        if(StringUtils.isNotEmpty(mediaId)) {
            wxMpKefuMessage.setMediaId(mediaId);
        }
        if(StringUtils.isNotEmpty(title)) {
            wxMpKefuMessage.setTitle(title);
        }
        if(StringUtils.isNotEmpty(description)) {
            wxMpKefuMessage.setDescription(description);
        }
        if(StringUtils.isNotEmpty(content)) {
            wxMpKefuMessage.setContent(content);
        }
        wxMpKefuMessage.setMsgType(type);
        return wxMpKefuMessage;
    }

    /**
     * 组装各类型消息
     * @param ruleContent
     * @param toUser
     * @param fromUser
     * @return
     */
    private String replyRuleContentMsg(MessageReplyRuleContent ruleContent,String toUser, String fromUser) {
        String result = null;
        WechatMessageType type = ruleContent.getType();
        if(type.equals(WechatMessageType.TEXT)) {
            result = textMsg(toUser,fromUser,ruleContent.getContent());
        } else if(type.equals(WechatMessageType.IMAGE)) {
            result = imageMsg(toUser,fromUser,ruleContent.getMediaId());
        } else if(type.equals(WechatMessageType.VOICE)) {
            result = voiceMsg(toUser,fromUser,ruleContent.getMediaId());
        } else if(type.equals(WechatMessageType.VIDEO)) {
            result = videoMsg(toUser,fromUser,ruleContent.getMediaId(),ruleContent.getMediaTitle(),ruleContent.getMediaDesc());
        } else if(type.equals(WechatMessageType.NEWS)) {
            result = newsMsg(toUser,fromUser,ruleContent.getMediaTitle(),ruleContent.getMediaDesc(),ruleContent.getMediaPicUrl(),ruleContent.getMediaUrl());
        }
        return result;
    }

    /**
     * 回复文本消息
     * @param toUser
     * @param fromUser
     * @param content
     * @return
     */
    private String textMsg(String toUser, String fromUser,String content) {
        WxMpXmlOutMessage m = WxMpXmlOutMessage.TEXT().content(content).fromUser(toUser).toUser(fromUser).build();
        return m.toXml();
    }

    /**
     * 回复图片消息
     * @param toUser
     * @param fromUser
     * @param mediaId
     * @return
     */
    private String imageMsg(String toUser, String fromUser, String mediaId) {
        WxMpXmlOutMessage m = WxMpXmlOutMessage.IMAGE().mediaId(mediaId).fromUser(toUser).toUser(fromUser).build();
        return m.toXml();
    }

    /**
     * 回复语音消息
     * @param toUser
     * @param fromUser
     * @param mediaId
     * @return
     */
    private String voiceMsg(String toUser, String fromUser, String mediaId) {
        WxMpXmlOutMessage m = WxMpXmlOutMessage.VOICE().mediaId(mediaId).fromUser(toUser).toUser(fromUser).build();
        return m.toXml();
    }

    /**
     * 回复视频消息
     * @param toUser
     * @param fromUser
     * @param mediaId
     * @param title
     * @param desc
     * @return
     */
    private String videoMsg(String toUser, String fromUser, String mediaId, String title, String desc) {
        WxMpXmlOutMessage m = WxMpXmlOutMessage.VIDEO().title(title).description(desc).mediaId(mediaId).fromUser(toUser).toUser(fromUser).build();
        return m.toXml();
    }

    /**
     * 回复图文消息
     * @param toUser
     * @param fromUser
     * @param title
     * @param desc
     * @param picUrl
     * @param url
     * @return
     */
    private String newsMsg(String toUser, String fromUser, String title, String desc, String picUrl, String url) {
        WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
        item.setDescription(desc);
        item.setPicUrl(picUrl);
        item.setTitle(title);
        item.setUrl(url);
        WxMpXmlOutMessage m = WxMpXmlOutMessage.NEWS().fromUser(toUser).toUser(fromUser).addArticle(item).build();
        return m.toXml();
    }

}
